#!/usr/bin/env bash


set_shell_options() {
    set -e
    set -u
    set -o pipefail
}


remove_shell_options() {
    set +e
    set +u
    set +o pipefail
}


# https://mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3
cmd1_and_cmd2_or_cmd3() {
    echo "${FUNCNAME[0]}"
    i=0
    true && ((i++)) || ((i--))
    echo "$i"
}


wrong() {
    echo "${FUNCNAME[0]}"
    i=0
    true && ((i++)) || ((i--))  # WRONG!
    echo "$i"                   # Prints 0
}


dumb_luck() {
    echo "${FUNCNAME[0]}"
    i=0
    true && (( ++i )) || (( --i ))  # STILL WRONG!
    echo "$i"                       # Prints 1 by dumb luck
}


so_called_correct() {
    echo "${FUNCNAME[0]}"
    i=0
    if true; then
        ((i++))
    else
        ((i--))
    fi
    echo "$i"    # Prints 1
}


so_called_correct_so_called_fixed() {
    echo "${FUNCNAME[0]}"
    local status=
    i=0
    if ! true; then
        status="fail"
    elif ! ((i++)); then
        status="fail"
    fi


    if [[ "$status" == "fail" ]]; then
        if ! ((i--)); then
            echo "ERROR: we caught a fail"
        fi
    fi


    echo "$i"    # Prints 1
}


# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html#The-Set-Builtin
correct_has_issues_with_shell_options() {
    echo "${FUNCNAME[0]}"


    set_shell_options


    i=0
    if true; then
        ((i++))
    else
        ((i--))
    fi
    remove_shell_options
    echo "$i"    # Prints 1
}


correct_has_issues_with_shell_options_caught() {
    echo "${FUNCNAME[0]}"


    set_shell_options


    i=0
    if true; then
        ((i++)) || echo "ERROR: failed to inc"
    else
        ((i--)) || echo "ERROR: failed to dec"
    fi
    remove_shell_options
    echo "$i"    # Prints 1
}


cmd1_and_cmd2_or_cmd3_has_issues_with_shell_options() {
    echo "${FUNCNAME[0]}"
    set_shell_options
    local i=
    true && i=1 || i=-1
    remove_shell_options
    echo "$i"
}


main() {
    echo "We want all to return 1 and not see any errors:"
    echo ""
    cmd1_and_cmd2_or_cmd3
    wrong
    dumb_luck
    so_called_correct
    so_called_correct_so_called_fixed
    correct_has_issues_with_shell_options || echo "need it but will not see it"
    correct_has_issues_with_shell_options_caught
    cmd1_and_cmd2_or_cmd3_has_issues_with_shell_options
    so_called_correct
}


main "$@"
